home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / admin / linuxcon.000 / linuxcon / linuxconf-1.6 / fstab / fstab1.c < prev    next >
C/C++ Source or Header  |  1996-04-27  |  8KB  |  382 lines

  1. #include <string.h>
  2. #include <stdlib.h>
  3. #include "fstab.h"
  4. #include "../paths.h"
  5. #include "internal.h"
  6.  
  7. FSTAB_HELP_FILE help_fstab ("fstab");
  8. static CONFIG_FILE f_fstab (ETC_FSTAB,help_fstab,CONFIGF_MANAGED);
  9.  
  10. PRIVATE void FSTAB_ENTRY::init()
  11. {
  12.     valid = 0;
  13.     memset (&bool_opt,0,sizeof(bool_opt));
  14.     msdos_opt.uid = msdos_opt.gid = msdos_opt.perm = MSDOS_OPT_UNUSE;
  15.     nfs_opt.rsize = nfs_opt.wsize = NFS_OPT_UNUSE;
  16.     nfs_opt.soft = nfs_opt.bg = 0;
  17.     dumpfreq = fsckpriority = 1;
  18. }
  19.  
  20. PUBLIC FSTAB_ENTRY::FSTAB_ENTRY()
  21. {
  22.     init();
  23. }
  24.  
  25. /*
  26.     Analyse the option string xxx,yyy,zzz=val,...
  27.     Some option are "known" by fsconf. Unknown one are left in
  28.     an "option" string editable by the user. The known one have
  29.     there own field in the FSTAB_ENTRY structure.
  30. */
  31. PUBLIC void FSTAB_ENTRY::parseopt(char *opts)
  32. {
  33.     char other[200];
  34.     other[0] = '\0';
  35.     while (*opts != '\0'){
  36.         char *debut = opts;
  37.         char *equal = "";
  38.         int seen_equal = 0;
  39.         while (1){
  40.             char *pt_carac = opts;
  41.             char carac = *opts++;
  42.             if (carac == '\0'){
  43.                 opts--;
  44.                 break;
  45.             }else if (carac == ','){
  46.                 *pt_carac = '\0';
  47.                 break;
  48.             }else if (carac == '='){
  49.                 equal = opts;
  50.                 *pt_carac = '\0';
  51.                 seen_equal = 1;
  52.             }
  53.         }
  54.         if (strcmp(debut,"defaults")==0){
  55.             // Do nothing here. The keyword defaults
  56.             // is silently write back if no other option
  57.             // is specified.
  58.         }else if (strcmp(debut,"conv")==0){
  59.             msdos_opt.conv.setfrom(equal);
  60.         }else if (strcmp(debut,"uid")==0){
  61.             msdos_opt.uid = atoi(equal);
  62.         }else if (strcmp(debut,"gid")==0){
  63.             msdos_opt.gid = atoi(equal);
  64.         }else if (strcmp(debut,"perm")==0){
  65.             msdos_opt.perm = atoi(equal);
  66.         }else if (strcmp(debut,"noexec")==0){
  67.             bool_opt.noexec = 1;
  68.         }else if (strcmp(debut,"exec")==0){
  69.             bool_opt.noexec = 0;
  70.         }else if (strcmp(debut,"nosuid")==0){
  71.             bool_opt.nosuid = 1;
  72.         }else if (strcmp(debut,"suid")==0){
  73.             bool_opt.nosuid = 0;
  74.         }else if (strcmp(debut,"nodev")==0){
  75.             bool_opt.nodev = 1;
  76.         }else if (strcmp(debut,"dev")==0){
  77.             bool_opt.nodev = 0;
  78.         }else if (strcmp(debut,"user")==0){
  79.             bool_opt.user = 1;
  80.             bool_opt.nodev = 1;
  81.             bool_opt.noexec = 1;
  82.             bool_opt.nosuid = 1;
  83.         }else if (strcmp(debut,"ro")==0){
  84.             bool_opt.readonly = 1;
  85.         }else if (strcmp(debut,"rw")==0){
  86.             bool_opt.readonly = 0;
  87.         }else if (strcmp(debut,"noauto")==0){
  88.             bool_opt.noauto = 1;
  89.         }else if (strcmp(debut,"soft")==0){
  90.             nfs_opt.soft = 1;
  91.         }else if (strcmp(debut,"bg")==0){
  92.             nfs_opt.bg = 1;
  93.         }else if (strcmp(debut,"rsize")==0){
  94.             nfs_opt.rsize = atoi(equal);
  95.         }else if (strcmp(debut,"wsize")==0){
  96.             nfs_opt.wsize = atoi(equal);
  97.         }else if (strcmp(debut,"addr")!=0){
  98.             // This is the other option still unknown by linuxconf
  99.             // note that the simili addr option used by NFS in /etc/mtab
  100.             // is ignored.
  101.             if (other[0] != '\0') strcat (other,",");
  102.             strcat (other,debut);
  103.             if (seen_equal){
  104.                 strcat (other,"=");
  105.                 strcat (other,equal);
  106.             }
  107.         }
  108.     }
  109.     options.setfrom (other);
  110. }
  111. /*
  112.     Build an FSTAB_ENTRY from a line of the /etc/fstab file
  113. */
  114. PUBLIC FSTAB_ENTRY::FSTAB_ENTRY (const char *line)
  115. {
  116.     init();
  117.     line = str_skip (line);
  118.     if (*line != '\0'){
  119.         if (*line == '#'){
  120.             comment.setfrom(line);
  121.         }else{
  122.             char buf[1000];
  123.             strcpy (buf,line);
  124.             char *pt1 = strtok (buf," \t");
  125.             char *pt2 = strtok (NULL," \t");
  126.             char *pt3 = strtok (NULL," \t");
  127.             char *pt4 = strtok (NULL," \t");
  128.             char *pt5 = strtok (NULL," \t");
  129.             char *pt6 = strtok (NULL," \t");
  130.             if (pt4 != NULL){
  131.                 source.setfrom(pt1);
  132.                 mpoint.setfrom(pt2);
  133.                 type.setfrom (pt3);
  134.                 parseopt (pt4);
  135.                 if (pt5 != NULL) dumpfreq = atoi(pt5);
  136.                 if (pt6 != NULL) fsckpriority = atoi(pt6);
  137.                 valid = 1;
  138.             }else{
  139.                 comment.setfrom(str_skip(line));
  140.             }
  141.         }
  142.     }
  143. }
  144. static void opt_put_if (
  145.     char *out,
  146.     char bool_opt,
  147.     const char *name,
  148.     int &was_written)
  149. {
  150.     if (bool_opt){
  151.         if (was_written) strcat (out,",");
  152.         was_written = 1;
  153.         strcat (out,name);
  154.     }
  155. }
  156. static void opt_put_if (
  157.     char *out,
  158.     char bool_opt,
  159.     const char *noname,
  160.     const char *name,
  161.     int &was_written)
  162. {
  163.     if (was_written) strcat (out,",");
  164.     was_written = 1;
  165.     strcat (out,bool_opt ? noname : name);
  166. }
  167. static void opt_put_if (
  168.     char *out,
  169.     int value,
  170.     const char *name,
  171.     int &was_written)
  172. {
  173.     if (value != MSDOS_OPT_UNUSE){
  174.         if (was_written) strcat (out,",");
  175.         was_written = 1;
  176.         char buf[100];
  177.         sprintf (buf,"%s=%d",name,value);
  178.         strcat (out,buf);
  179.     }
  180. }
  181. static void opt_put_if (
  182.     char *out,
  183.     const char *value,
  184.     const char *name,
  185.     int &was_written)
  186. {
  187.     if (value[0] != '\0'){
  188.         if (was_written) strcat (out,",");
  189.         was_written = 1;
  190.         char buf[100];
  191.         sprintf (buf,"%s=%s",name,value);
  192.         strcat (out,buf);
  193.     }
  194. }
  195.  
  196. /*
  197.     Format all the mount option in a string suitable for the mount command
  198.     if tosave != 0, it also adds the options only meaningful in /etc/fstab
  199.     (user,noauto,...)
  200. */
  201. PUBLIC void FSTAB_ENTRY::format_opt(int tosave, char *str) const
  202. {
  203.     int one = 0;
  204.     str[0] = '\0';
  205.     if (tosave) opt_put_if (str,bool_opt.user,"user",one);
  206.     opt_put_if (str,bool_opt.noexec,"noexec","exec",one);
  207.     opt_put_if (str,bool_opt.nodev,"nodev","dev",one);
  208.     opt_put_if (str,bool_opt.nosuid,"nosuid","suid",one);
  209.     opt_put_if (str,bool_opt.readonly,"ro","rw",one);
  210.     if (tosave) opt_put_if (str,bool_opt.noauto,"noauto",one);
  211.     opt_put_if (str,msdos_opt.conv.get(),"conv",one);
  212.     opt_put_if (str,msdos_opt.uid,"uid",one);
  213.     opt_put_if (str,msdos_opt.gid,"gid",one);
  214.     opt_put_if (str,msdos_opt.perm,"perm",one);
  215.     opt_put_if (str,nfs_opt.bg,"bg",one);
  216.     opt_put_if (str,nfs_opt.soft,"soft",one);
  217.     opt_put_if (str,nfs_opt.rsize,"rsize",one);
  218.     opt_put_if (str,nfs_opt.wsize,"wsize",one);
  219.     if (!options.is_empty()){
  220.         if (one) strcat (str,",");
  221.         strcat (str,options.get());
  222.     }else if (!one){
  223.         if (tosave) strcpy (str,"defaults");
  224.     }
  225. }
  226.  
  227. /*
  228.     Write an entry into /etc/fstab
  229. */
  230. PUBLIC void FSTAB_ENTRY::print (FILE *fout) const
  231. {
  232.     if (valid){
  233.         fprintf (fout,"%s\t%s\t%s\t",source.get(),mpoint.get()
  234.             ,type.get());
  235.         char str[200];
  236.         format_opt (1,str);
  237.         fprintf (fout," %s %d %d",str,dumpfreq,fsckpriority);
  238.     }else{
  239.         fputs (comment.get(),fout);
  240.     }
  241.     fputc ('\n',fout);
  242. }
  243.  
  244. /*
  245.     Return != 0 if this entry is ok (not a comment).
  246. */
  247. PUBLIC int FSTAB_ENTRY::is_valid() const
  248. {
  249.     return valid;
  250. }
  251.  
  252.  
  253. /*
  254.     Tell if this mount should be done at boot time.
  255. */
  256. PUBLIC int FSTAB_ENTRY::is_auto()
  257. {
  258.     return !bool_opt.noauto;
  259. }
  260.  
  261. /*
  262.     Return != 0 if the entry describe a mount of a remote volume
  263.     either with NFS or SMBFS.
  264. */
  265. PUBLIC int FSTAB_ENTRY::is_remote() const
  266. {
  267.     return type.cmp("nfs")==0 || type.cmp("smbfs")==0;
  268. }
  269. /*
  270.     Return != 0 if the entry describe a swap file or partition.
  271. */
  272. PUBLIC int FSTAB_ENTRY::is_swap() const
  273. {
  274.     return type.cmp("swap")==0;
  275. }
  276. /*
  277.     Return the file system type ID
  278. */
  279. PUBLIC FSTAB_ENTRY_TYPE FSTAB_ENTRY::gettype() const
  280. {
  281.     FSTAB_ENTRY_TYPE ret = FSTAB_ENTRY_LOCAL;
  282.     if (is_swap()){
  283.         ret = FSTAB_ENTRY_SWAP;
  284.     }else if (type.cmp("nfs")==0){
  285.         ret = FSTAB_ENTRY_NFS;
  286.     }else if (type.cmp("smbfs")==0){
  287.         ret = FSTAB_ENTRY_SAMBA;
  288.     }else if (type.cmp("proc")==0){
  289.         ret = FSTAB_ENTRY_PROC;
  290.     }
  291.     return ret;
  292. }
  293. /*
  294.     Return the file systeme type (ascii).
  295. */
  296. PUBLIC const char *FSTAB_ENTRY::getfs() const
  297. {
  298.     return type.get();
  299. }
  300.  
  301. /*
  302.     Return the source of the mount (either the device or the remote volume)
  303. */
  304. PUBLIC const char *FSTAB_ENTRY::getsource() const
  305. {
  306.     return source.get();
  307. }
  308.  
  309. /*
  310.     Record a new device / remote volume for a FSTAB_ENTRY
  311. */
  312. PUBLIC void FSTAB_ENTRY::setsource(const char *path)
  313. {
  314.     source.setfrom (path);
  315.     setmodified();
  316. }
  317. /*
  318.     Return the mount point
  319. */
  320. PUBLIC const char *FSTAB_ENTRY::getmpoint() const
  321. {
  322.     return mpoint.get();
  323. }
  324.  
  325. /*
  326.     Return the comment of the entry
  327. */
  328. PUBLIC const char *FSTAB_ENTRY::getcomment()
  329. {
  330.     return comment.get();
  331. }
  332.  
  333.  
  334. PUBLIC FSTAB::FSTAB ()
  335. {
  336.     FILE *fin = f_fstab.fopen("r");
  337.     if (fin != NULL){
  338.         char buf[1000];
  339.         while (fgets_cont(buf,sizeof(buf)-1,fin) != -1){
  340.             add (new FSTAB_ENTRY(buf));
  341.         }
  342.         fclose (fin);
  343.     }
  344.     rstmodified();
  345. }
  346. /*
  347.     Return one entry of the fstab file.
  348.     Returne NULL if the entry is out of range.
  349. */
  350. PUBLIC FSTAB_ENTRY *FSTAB_GEN::getitem(int no)
  351. {
  352.     return (FSTAB_ENTRY*)ARRAY::getitem(no);
  353. }
  354.  
  355. /*
  356.     Write a /etc/fstab file
  357.     Return -1 if any error.
  358. */
  359. PUBLIC int FSTAB::write ()
  360. {
  361.     int ret = -1;
  362.     FILE *fout = f_fstab.fopen ("w");
  363.     if (fout != NULL){
  364.         ret = 0;
  365.         for (int i=0; i<nb; i++) getitem(i)->print (fout);
  366.         fclose (fout);
  367.     }
  368.     return ret;
  369. }
  370.  
  371. #ifdef TEST
  372.  
  373. int main (int argc, char *argv[])
  374. {
  375.     FSTAB fs;
  376.     fs.write();
  377.     return 0;
  378. }
  379.  
  380. #endif
  381.  
  382.